#pragma once

#include "Socket.hpp"
#include "Protocol.hpp"
#include "NetCal.hpp"

#include <functional>

using process_t = std::function<std::shared_ptr<Response>(std::shared_ptr<Request>)>;

class IOService
{
public:
    IOService(process_t process) : _process(process)
    {
    }
    ~IOService()
    {
    }
    void IOExcute(SockSPtr sockfd, InetAddr &addr)
    {
        std::string buffer;
        while (1)
        {
            int n = sockfd->Recv(&buffer);
            if (n <= 0)
            {
                LOG(INFO, "client %s quit\n", addr.AddrStr().c_str());
                break;
            }
            std::cout<<buffer<<std::endl;

            std::string cmd = Decode(buffer);
            if(cmd.empty()) 
            {
                std::cout<<"cmd is empty"<<std::endl;
                continue;
            }
            std::cout<<"cmd: "<<cmd<<std::endl;

            auto req = Factory::BuildRequestDefault();
            req->DeSerialize(cmd);

            auto resp = _process(req);

            std::string ret;
            resp->Serialize(&ret);
            if(ret.empty()) continue;

            ret = Encode(ret);
            sockfd->Send(ret);
            std::cout<<"Send: "<<ret<<std::endl;
        }
    }
private:
    process_t _process;
};
